<?php

namespace app\health\service;

use fast\Http;
use think\Env;
use think\Exception;
use think\Log;

/**
 * 福禄聚采开放服务接口
 */
class FuluOpenService
{
    public function __construct()
    {

    }

    /**
     * 返回baseurl
     * @return string
     */
    private function baseUrl(): string
    {
        return Env::get('fulu.url', 'https://pre-openapi.fulu.com/api/getway');
    }

    private function appKey()
    {
        return Env::get('fulu.app_key', 'i4esv1l+76l/7NQCL3QudG90Fq+YgVfFGJAWgT+7qO1Bm9o/adG/1iwO2qXsAXNB');
    }

    private function appSecret()
    {
        return Env::get('fulu.AppSecret', '0a091b3aa4324435aab703142518a8f7');
    }

    /**
     * 请求参数
     * @param $method
     * @param array $bizContent
     * @return false|string
     */
    private function requestParams($method, array $bizContent = [])
    {
        $params         = [
            'app_key'        => $this->appKey(),
            'method'         => $method,
            'timestamp'      => date('Y-m-d H:i:s'),
            'version'        => '2.0',
            'format'         => 'json',
            'charset'        => 'utf-8',
            'sign_type'      => 'md5',
            'app_auth_token' => '',
            'biz_content'    => json_encode($bizContent, JSON_UNESCAPED_UNICODE)
        ];
        $params['sign'] = $this->getSign($params);
        return json_encode($params);
    }

    /**
     * 获取签名
     * @param $Parameters
     * @return string
     */
    private function getSign($Parameters)
    {
        //签名步骤一：把字典json序列化
        $json = json_encode($Parameters, 320);
        //签名步骤二：转化为数组
        $jsonArr = $this->mb_str_split($json);
        //签名步骤三：排序
        sort($jsonArr);
        //签名步骤四：转化为字符串
        $string = implode('', $jsonArr);
        //签名步骤五：在string后加入secret
        $string .= $this->appSecret();
        //签名步骤六：MD5加密
        return strtolower(md5($string));
    }

    /**
     * 可将字符串中中文拆分成字符数组
     * @param $str
     * @return array|false|string[]
     */
    private function mb_str_split($str)
    {
        return preg_split('/(?<!^)(?!$)/u', $str);
    }

    /**
     * 请求接口
     * @param $params
     * @return mixed
     */
    private function request($params)
    {
        try {
            $response = Http::post($this->baseUrl(), $params, [
                CURLOPT_HTTPHEADER => ['Content-Type: application/json']
            ]);
            $response = json_decode($response, true);
            if (!$response) {
                throw new \Exception('HTTP请求异常');
            }
            if ($response['code'] === 0) {
                $response['result'] = json_decode($response['result'], true);
                return $response;
            }
            throw new \Exception($response['message'], $response['code']);
        } catch (\Exception $exception) {
            return ['error' => $exception->getMessage(), 'error_code' => $exception->getCode(), 'params' => $params];
        }
    }

    /**
     * 直充下单接口
     * @param $customerOrderNo
     * @param $productId
     * @param $chargeAccount
     * @return mixed|true
     */
    public function orderDirect($customerOrderNo, $productId, $chargeAccount)
    {
        if ($this->baseUrl() === 'https://pre-openapi.fulu.com/api/getway') {
            $productId = '10000586';
        }
        $params   = $this->requestParams('fulu.order.direct.add', [
            'product_id'        => $productId,
            'customer_order_no' => $customerOrderNo,
            'charge_account'    => $chargeAccount,
            'buy_num'           => 1,
        ]);
        $response = $this->request($params);
        Log::debug('[福禄直充下单参数]:' . json_encode($params));
        Log::debug('[福禄直充下单结果]:' . json_encode($response, JSON_UNESCAPED_UNICODE));
        if (isset($response['error_code'])) {
            return $response['error'];
        }
        return true;
    }

    /**
     * 获取订单充值状态
     * @param $customerOrderNo
     * @return string
     * success：成功，processing：处理中，failed：失败，untreated：未处理
     */
    public function orderInfoGet($customerOrderNo): string
    {
        $response = $this->request($this->requestParams('fulu.order.info.get', [
            'customer_order_no' => $customerOrderNo,
        ]));
        Log::debug('[福禄订单查询]:' . json_encode($response, JSON_UNESCAPED_UNICODE));
        if (isset($response['error_code'])) {
            return $response['error'];
        }
        return $response['result']['order_state'];
    }
}